package com.zslibrary.Protocol;

import android.os.SystemClock;

import com.zslibrary.BusMaster.HandleError;
import com.zslibrary.Enum.PipeResultDefine;
import com.zslibrary.Enum.ProducingStatusDefine;
import com.zslibrary.Enum.Protocol;
import com.zslibrary.Enum.StateEventDefine;
import com.zslibrary.Enum.StatusDefine;
import com.zslibrary.Pipe.Pipe;

import com.zslibrary.Structure.ConfigRecipeStrcut;
import com.zslibrary.Structure.ErrorStruct;
import com.zslibrary.Structure.GeneralRequestStruct;
import com.zslibrary.Structure.JoblistStruct;
import com.zslibrary.Structure.MessageStruct;
import com.zslibrary.Structure.ProductInfoStruct;
import com.zslibrary.Structure.TreeDefineStruct;
import com.zslibrary.Tools.FrameBuilder;
import com.zslibrary.Tools.ZSLog;

public class MakeProduct {
    static private Boolean startProducing=false;
    static private Boolean doneProducing=false;
    static private Boolean productFinish=false;
    static private Boolean sayGoodBye=false;
    static private Boolean isProductSuccess=false;
    static private short currentStep=0;
    static private short totalStep=0;

    public static @StateEventDefine.StateEvent int makeProduct(ConfigRecipeStrcut[] recipe, int craftId, final Pipe pipe){
        ProductInfoStruct productInfo=null;
        for(int i=0;i<2;i++){
            productInfo= JobList.generateJoblist(recipe,craftId);
            if(productInfo!=null)
                break;
            SystemClock.sleep(200);
        }
        if(productInfo==null) {
            ZSLog.d("product error");
            ErrorStruct error=new ErrorStruct("EOE_01",true,true);
            HandleError.setError(error);
            return StateEventDefine.EVT_NONE;
        }
        GeneralRequestStruct request=getJobListRequest(productInfo);
        Pipe.HandleMessageCallback callback=new Pipe.HandleMessageCallback() {
            @Override
            public Boolean handle(MessageStruct[] messages) {
                for(MessageStruct message:messages){
                    switch (message.messageId){
                        case Protocol.MSG_SET_COMP_ERR:{
                            CommonMessage.processSetError(message);
                        }break;

                        case Protocol.MSG_CLEAR_COMP_ERR:{
                            CommonMessage.processClrError(message);
                        }break;

                        case Protocol.MSG_BOARD_RESET:{
                            pipe.interruptAsynchonousPipe();    /*可被终止*/
                        }break;

                        case Protocol.MSG_PRODUCT_ON_PROGRESS: {
                            FrameBuilder builder=new FrameBuilder(message.messageData);
                            currentStep=(short)builder.popData(2);
                            totalStep=(short)builder.popData(2);
                            //ZSLog.d("product step:"+currentStep);
                        }break;

                        case Protocol.MSG_PRODUCT_DONE:{
                            //2020_02_11 modify
//                            if(startProducing)
//                                doneProducing=true;
                            ZSLog.d("product done");
                            return true;    /*制作完成,无论成功失败*/
                        }

                        case Protocol.MSG_PRODUCT_SHOW_MSG:{
                            FrameBuilder builder=new FrameBuilder(message.messageData);
                            int pMessage=builder.popData(2);
                            if(pMessage==5){
                                ZSLog.d("product finish");
                                productFinish=true;
                                isProductSuccess=true;
                            }else if(pMessage==6){
                                ZSLog.d("product goodbye");
                                sayGoodBye=true;
                            }
                        }break;

                        case Protocol.MSG_BOARD_STATUS:{
                            FrameBuilder builder=new FrameBuilder(message.messageData);
                            int status=builder.popData(4);
                            if(status== StatusDefine.CMS_PRODUCT){
                                startProducing=true;
                            }
                            //ZSLog.d("report status:"+status);
                        }break;

                        default:
                            break;
                    }
                }
                return false;
            }
        };
        currentStep=0;
        totalStep=0;
        //产品状态标志位
        initStatus();

        @PipeResultDefine.PipeResult int result=pipe.asynchronousPipe(request,callback,300000);
        doneProducing=true; //2020_02_11 add
        if(result==PipeResultDefine.ASYNC_ERROR)
            return StateEventDefine.EVT_DISCONNECT;
        else if(result==PipeResultDefine.ASYNC_INTERRUPT)
            return StateEventDefine.EVT_RESET;
        else if(result==PipeResultDefine.ASYNC_BUSY)
            return StateEventDefine.EVT_EXECUTE;
        else if(result==PipeResultDefine.ASYNC_OK)
            return StateEventDefine.EVT_NONE;
        return StateEventDefine.EVT_NONE;
    }

    public static @ProducingStatusDefine.ProducingStatus int getProductStatus(){
        //2020_02_11 add
        if(doneProducing) {
            initStatus();
        }
        //2020_02_11 modify
//        if(sayGoodBye){
//            if(productFinish){
//                sayGoodBye=false;
//                productFinish=false;
//                return ProducingStatusDefine.P_TAKE_AWAY;
//            }
//        }
        if(sayGoodBye&&productFinish)//2020_02_11 modify
            return ProducingStatusDefine.P_TAKE_AWAY;

        if(productFinish)
            return ProducingStatusDefine.P_FINISH;
        if(startProducing)  //2020_02_11 add
            return ProducingStatusDefine.P_PRODUCING;
        return ProducingStatusDefine.P_IDLE;    //2020_02_11 add
    }

    //2020_02_11 add
    public static Boolean getProductResult(){
        if(isProductSuccess){
            isProductSuccess=false;
            return true;
        }
        return false;
    }

    public static float getStepProgress(){
        if(totalStep==0)
            return 0;
        return currentStep/(float)totalStep;
    }

    private static void initStatus(){
        doneProducing=false;
        sayGoodBye=false;
        productFinish=false;
        startProducing=false;
    }

    private static GeneralRequestStruct getJobListRequest(ProductInfoStruct productInfo){
        GeneralRequestStruct request=new GeneralRequestStruct();
        int dataLen=productInfo.treeLength*12+productInfo.joblistsLength*27+8;
        FrameBuilder dataBuilder=new FrameBuilder(dataLen);
        request.requstId= Protocol.MSG_MAKE_PRODUCT;
        request.dataLength=(short)dataLen;
        dataBuilder.append(productInfo.productId);
        dataBuilder.append(productInfo.joblistsLength);
        for(JoblistStruct joblist:productInfo.joblist){
            if(joblist==null)
                break;
            dataBuilder.append(joblist.componentId);
            dataBuilder.append(joblist.transformation);
            dataBuilder.append(joblist.dosage);
            dataBuilder.append(joblist.ingredient);
            dataBuilder.append(joblist.unit);
        }
        dataBuilder.append(productInfo.treeLength);
        for(TreeDefineStruct tree:productInfo.tree){
            if(tree==null)
                break;
            dataBuilder.append(tree.sender.componentId);
            dataBuilder.append(tree.sender.gateId);
            dataBuilder.append(tree.sendTreeNr);
            dataBuilder.append(tree.sendFlow);
            dataBuilder.append(tree.receiver.componentId);
            dataBuilder.append(tree.receiver.gateId);
            dataBuilder.append(tree.receiveTreeNr);
            dataBuilder.append(tree.receiveFlow);
        }
        dataBuilder.append(productInfo.isJug);
        dataBuilder.append(productInfo.circles);
        request.data=dataBuilder.toBytes();
        return request;
    }
}
